package cn.ywyu.classfinal;

import cn.ywyu.classfinal.constant.Const;
import cn.ywyu.classfinal.jar.JarDecryptor;
import cn.ywyu.classfinal.util.*;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.instrument.Instrumentation;
import java.util.Arrays;
import java.util.Properties;

/**
 * 监听类加载
 */
public class CoreAgent {
    /**
     * man方法执行前调用
     *
     * @param args 参数
     * @param inst inst
     */
    public static void premain(String args, Instrumentation inst) {
        Const.printInfo();

        //读取jar隐藏的密码，无密码启动模式(jar)
        char[] pwd = JarDecryptor.readPassFromJar(new File(JarUtils.getRootPath(null)));

        //参读取密码配置文件
        if (StrUtils.isEmpty(pwd)) {
            Log.debug("读取密码文件");
            pwd = readPasswordFromFile();
        }



        //还是没有获取密码，退出
        if (StrUtils.isEmpty(pwd)) {
            Log.println("\nERROR: Startup failed, could not get the password.\n");
            System.exit(0);
        }

        //验证密码,jar包是才验证
        byte[] passHash = JarDecryptor.readEncryptedFile(new File(JarUtils.getRootPath(null)), Const.CONFIG_PASS_HASH);
        if (passHash != null) {
            char[] p1 = StrUtils.toChars(passHash);
            char[] p2 = EncryptUtils.md5(StrUtils.merger(pwd, EncryptUtils.SALT));
            p2 = EncryptUtils.md5(StrUtils.merger(EncryptUtils.SALT, p2));
            if (!Arrays.equals(p1, p2)) {
                Log.println("\nERROR: Startup failed, invalid password.\n");
                System.exit(0);
            }
        }

        //GO
        if (inst != null) {
            AgentTransformer tran = new AgentTransformer(pwd);
            inst.addTransformer(tran);
        }
    }

    /**
     * 从文件读取密码
     *
     * @return 密码
     */
    public static char[] readPasswordFromFile() {
        String passPath = JarDecryptor.readPassPathFromJar(new File(JarUtils.getRootPath(null)));
        if (passPath == null || passPath.equals("")) {
            return null;
        }
        File config = new File(passPath);
        if (!config.exists()) {
            return null;
        }
        Properties properties = new Properties();
        try {
            properties.load(new FileInputStream(config));
        } catch (IOException e) {
            Log.println("\nERROR: Read File IOException");
            return null;
        }
        return properties.getProperty("KEY").trim().toCharArray();
    }
}
